home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / Windows / wmesa_stereo.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  46KB  |  1,873 lines

  1. /*
  2.     WMesa_stereo.c
  3. */
  4. // Stereo display feature added by Li Wei
  5. // Updated 1996/10/06    11:16:15 CST
  6. // Paralell render feature added by Li Wei
  7. // liwei@aiar.xjtu.edu.cn
  8. // http://sun.aiar.xjtu.edu.cn
  9.  
  10. #define WMESA_STEREO_C
  11.  
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <wmesadef.h>
  16.  
  17. #include <GL\wmesa.h>
  18. #include "context.h"
  19. #include "dd.h"
  20. #include "xform.h"
  21. #include "vb.h"
  22. #include "matrix.h"
  23. #include "depth.h"
  24.  
  25. #ifdef PROFILE
  26.     #include "profile.h"
  27. #endif
  28.  
  29. #include <wing.h>
  30.  
  31. // Code added by Li Wei to enable stereo display  and Paralell render
  32.  
  33.  
  34. /*#include "mesa_extend.h"*/
  35.  
  36. #if !defined(NO_STEREO)
  37.     
  38.     #include "gl\glu.h"
  39.     #include "stereo.h"
  40.     
  41.     PBYTE Buffer_Stereo;
  42.  
  43.     void WMesaCreateStereoBuffer(void);
  44.  
  45.     void WMesaInterleave( GLenum aView);
  46.  
  47.     void WMesaDestroyStereoBuffer(void);
  48.  
  49.     void WMesaShowStereo(GLuint list);
  50. #endif
  51. #if !defined(NO_PARALLEL)
  52.     #include "parallel.h"
  53. #endif
  54.  
  55. /* end of added code*/
  56.  
  57. /* Bit's used for dest: */
  58. #define FRONT_PIXMAP    1
  59. #define BACK_PIXMAP    2
  60. #define BACK_XIMAGE    4
  61.  
  62. static PWMC Current = NULL;
  63. WMesaContext WC = NULL;
  64.  
  65. #ifdef NDEBUG
  66.   #define assert(ignore)    ((void) 0)
  67. #else
  68.   void Mesa_Assert(void *Cond,void *File,unsigned Line)
  69.   {
  70.     char Msg[512];
  71.     sprintf(Msg,"%s %s %d",Cond,File,Line);
  72.     MessageBox(NULL,Msg,"Assertion failed.",MB_OK);
  73.     exit(1);
  74.   }
  75.   #define assert(e)    if (!e) Mesa_Assert(#e,__FILE__,__LINE__);
  76. #endif
  77.  
  78. #define DD_GETDC ((Current->db_flag) ? Current->dib.hDC : Current->hDC )
  79. #define DD_RELEASEDC
  80.  
  81. //#define BEGINGDICALL    if(Current->rgb_flag)wmFlushBits(Current);
  82. #define BEGINGDICALL
  83. //#define ENDGDICALL        if(Current->rgb_flag)wmGetBits(Current);
  84. #define ENDGDICALL
  85.  
  86. #define FLIP(Y)  (Current->height-(Y)-1)
  87.  
  88. #define STARTPROFILE 
  89. #define ENDPROFILE(PARA) 
  90.  
  91. static void FlushToFile(PWMC pwc, PSTR    szFile);
  92.  
  93. BOOL wmCreateBackingStore(PWMC pwc, long lxSize, long lySize);
  94.  
  95. BOOL wmDeleteBackingStore(PWMC pwc);
  96.  
  97. void wmCreatePalette( PWMC pwdc );
  98. BOOL wmSetDibColors(PWMC pwc);
  99. void wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b);
  100.  
  101. void wmCreateDIBSection(
  102.     HDC     hDC,
  103.     PWMC pwc,    // handle of device context
  104.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  105.     UINT iUsage    // color data type indicator: RGB values or palette indices
  106.     );
  107.  
  108. BOOL wmFlush(PWMC pwc);
  109.  
  110. /*
  111.  * Useful macros:
  112.    Modified from file osmesa.c     
  113.  */
  114.  
  115. #define PIXELADDR(X,Y)  ((GLbyte *)Current->pbPixels + (Current->height-Y)* Current->ScanWidth + (X)*nBypp)
  116.  
  117.  
  118. /* Finish all pending operations and synchronize. */
  119. static void finish(GLcontext* ctx)
  120. {
  121.    /* no op */
  122. }
  123.  
  124.  
  125. //
  126. // We cache all gl draw routines until a flush is made
  127. //
  128. static void flush(GLcontext* ctx)
  129. {
  130.     STARTPROFILE
  131.     if(Current->rgb_flag && !(Current->dib.fFlushed)&&!(Current->db_flag)){
  132.         wmFlush(Current);
  133.     }
  134.     ENDPROFILE(flush)
  135.    
  136. }
  137.  
  138.  
  139.  
  140. /*
  141.  * Set the color index used to clear the color buffer.
  142.  */
  143. static void clear_index(GLcontext* ctx, GLuint index)
  144. {
  145.   STARTPROFILE
  146.   Current->clearpixel = index;
  147.   ENDPROFILE(clear_index)
  148. }
  149.  
  150.  
  151.  
  152. /*
  153.  * Set the color used to clear the color buffer.
  154.  */
  155. static void clear_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  156. {
  157.   STARTPROFILE
  158.   Current->clearpixel=RGB(r, g, b );
  159.   ENDPROFILE(clear_color)
  160. }
  161.  
  162.  
  163.  
  164. /*
  165.  * Clear the specified region of the color buffer using the clear color
  166.  * or index as specified by one of the two functions above.
  167.  */
  168. static void clear(GLcontext* ctx, 
  169.                   GLboolean all,GLint x, GLint y, GLint width, GLint height )
  170. {
  171.     DWORD    dwColor;    
  172.     WORD    wColor;
  173.     LPDWORD    lpdw = (LPDWORD)Current->pbPixels;
  174.     LPWORD    lpw = (LPWORD)Current->pbPixels;
  175.     LPBYTE    lpb = Current->pbPixels;
  176.  
  177.     STARTPROFILE
  178.  
  179.     if (all){
  180.         x=y=0;
  181.         width=Current->width;
  182.         height=Current->height;
  183.     }
  184.     if (Current->rgb_flag==GL_TRUE){
  185.         if(Current->db_flag==GL_TRUE){
  186.             UINT    nBypp = Current->cColorBits / 8;
  187.             int        i = 0;
  188.             int        iSize;
  189.  
  190.             if(nBypp == 2){
  191.                 iSize = (Current->width * Current->height) / nBypp;
  192.  
  193.                 wColor = BGR16(GetRValue(Current->clearpixel), 
  194.                                GetGValue(Current->clearpixel), 
  195.                                GetBValue(Current->clearpixel));
  196.                 dwColor = MAKELONG(wColor, wColor);
  197.             }
  198.             else if(nBypp == 4){
  199.                 iSize = (Current->width * Current->height);
  200.  
  201.                 dwColor = BGR32(GetRValue(Current->clearpixel), 
  202.                                GetGValue(Current->clearpixel), 
  203.                                GetBValue(Current->clearpixel));
  204.             }
  205.             //
  206.             // This is the 24bit case
  207.             //
  208.             else {
  209.  
  210.                 iSize = (Current->width * Current->height) / nBypp;
  211.  
  212.                 dwColor = BGR24(GetRValue(Current->clearpixel), 
  213.                                GetGValue(Current->clearpixel), 
  214.                                GetBValue(Current->clearpixel));
  215.  
  216.  
  217.                 while(i < iSize){
  218.                     *lpdw = dwColor;
  219.                     lpb += nBypp;
  220.                     lpdw = (LPDWORD)lpb;
  221.                     i++;
  222.                 }
  223.  
  224.     //            ENDPROFILE(clear)
  225.  
  226.                 return;
  227.             }
  228.  
  229.             while(i < iSize){
  230.                 *lpdw = dwColor;
  231.                 lpdw++;
  232.                 i++;
  233.             }
  234.         }
  235.         else{ // For single buffer
  236.          HDC DC=DD_GETDC;
  237.          HPEN Pen=CreatePen(PS_SOLID,1,Current->clearpixel);
  238.          HBRUSH Brush=CreateSolidBrush(Current->clearpixel);
  239.          HPEN Old_Pen=SelectObject(DC,Pen);
  240.          HBRUSH Old_Brush=SelectObject(DC,Brush);
  241.          Rectangle(DC,x,y,x+width,y+height);
  242.          SelectObject(DC,Old_Pen);
  243.          SelectObject(DC,Old_Brush);
  244.          DeleteObject(Pen);
  245.          DeleteObject(Brush);
  246.          DD_RELEASEDC;
  247.           }
  248.     }
  249.     else {
  250.         int i;
  251.         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  252.         for (i=0; i<height; i++){
  253.             memset(Mem,Current->clearpixel,width);
  254.             Mem+=width;
  255.         }
  256.     }
  257.     ENDPROFILE(clear)
  258. }
  259.  
  260.  
  261.  
  262. /* Set the current color index. */
  263. static void set_index(GLcontext* ctx, GLuint index)
  264. {
  265.   STARTPROFILE
  266.   Current->pixel=index;
  267.   ENDPROFILE(set_index)
  268. }
  269.  
  270.  
  271.  
  272. /* Set the current RGBA color. */
  273. static void set_color( GLcontext* ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
  274. {
  275.   STARTPROFILE
  276.   Current->pixel = RGB( r, g, b );
  277.   ENDPROFILE(set_color)
  278. }
  279.  
  280.  
  281.  
  282. /* Set the index mode bitplane mask. */
  283. static GLboolean index_mask(GLcontext* ctx, GLuint mask)
  284. {
  285.    /* can't implement */
  286.    return GL_FALSE;
  287. }
  288.  
  289.  
  290.  
  291. /* Set the RGBA drawing mask. */
  292. static GLboolean color_mask( GLcontext* ctx,
  293.                              GLboolean rmask, GLboolean gmask,
  294.                              GLboolean bmask, GLboolean amask)
  295. {
  296.    /* can't implement */
  297.    return GL_FALSE;
  298. }
  299.  
  300.  
  301.  
  302. /*
  303.  * Set the pixel logic operation.  Return GL_TRUE if the device driver
  304.  * can perform the operation, otherwise return GL_FALSE.  If GL_FALSE
  305.  * is returned, the logic op will be done in software by Mesa.
  306.  */
  307. GLboolean logicop( GLcontext* ctx, GLenum op )
  308. {
  309.    /* can't implement */
  310.    return GL_FALSE;
  311. }
  312.  
  313.  
  314. static void dither( GLcontext* ctx, GLboolean enable )
  315. {
  316.    /* No op */
  317. }
  318.  
  319.  
  320.  
  321. static GLboolean set_buffer( GLcontext* ctx, GLenum mode )
  322. {
  323.    STARTPROFILE
  324.    /* TODO: this could be better */
  325.    if (mode==GL_FRONT || mode==GL_BACK) {
  326.       return GL_TRUE;
  327.    }
  328.    else {
  329.       return GL_FALSE;
  330.    }
  331.    ENDPROFILE(set_buffer)
  332. }
  333.  
  334.  
  335.  
  336. /* Return characteristics of the output buffer. */
  337. static void buffer_size( GLcontext* ctx, GLuint *width, GLuint *height /*, GLuint *depth */)
  338. {
  339.     
  340.     int New_Size;
  341.     RECT CR;
  342.     
  343.     STARTPROFILE
  344.     GetClientRect(Current->Window,&CR);
  345.  
  346.     *width=CR.right;
  347.     *height=CR.bottom;
  348. //    *depth = Current->depth;
  349.  
  350.     New_Size=((*width)!=Current->width) || ((*height)!=Current->height);
  351.  
  352.     if (New_Size){
  353.         Current->width=*width;
  354.         Current->height=*height;
  355.         Current->ScanWidth=Current->width;
  356.         if ((Current->ScanWidth%sizeof(long))!=0)
  357.             Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  358.  
  359.         if (Current->db_flag){
  360.             if (Current->rgb_flag==GL_TRUE){
  361.                 wmDeleteBackingStore(Current);
  362.                 wmCreateBackingStore(Current, Current->width, Current->height);
  363.             }
  364.             else{
  365.                 Current->ScanWidth=Current->width;
  366.                 if ((Current->ScanWidth%sizeof(long))!=0)
  367.                 Current->ScanWidth+=(sizeof(long)-(Current->ScanWidth%sizeof(long)));
  368.                 
  369.                 Current->IndexFormat->bmiHeader.biWidth=Current->width;
  370.  
  371.                 if (Current->IndexFormat->bmiHeader.biHeight<0)
  372.                     Current->IndexFormat->bmiHeader.biHeight=-(Current->height);
  373.                 else
  374.                     Current->IndexFormat->bmiHeader.biHeight=Current->height;
  375.  
  376.                 Current->Compat_BM=WinGCreateBitmap(Current->dib.hDC,Current->IndexFormat,&((void *) Current->ScreenMem));
  377.  
  378.                 DeleteObject(SelectObject(Current->dib.hDC,Current->Compat_BM));
  379.             }
  380. //Code added by Li Wei to enable stereo display
  381. // Recreate stereo buffer when stereo_flag is TRUE while parallelFlag is FALSE
  382. #if !defined(NO_STEREO)
  383.             if(stereo_flag
  384. #if !defined(NO_PARALLEL)
  385.                 &&!parallelFlag
  386. #endif                
  387.                 ) {
  388.             if(stereoBuffer == GL_TRUE)
  389.                 WMesaDestroyStereoBuffer();
  390.             WMesaCreateStereoBuffer();
  391.             }
  392. #endif
  393. //    Resize OsmesaBuffer if in Parallel mode
  394. #if !defined(NO_PARALLEL)    
  395.             if(parallelFlag)
  396.             PRSizeRenderBuffer(Current->width, Current->height,Current->ScanWidth,
  397.             Current->rgb_flag == GL_TRUE ? Current->pbPixels: Current->ScreenMem);
  398. #endif
  399. //end modification        
  400.         
  401.         }
  402.     }
  403.  
  404.    ENDPROFILE(buffer_size)
  405. }
  406.  
  407.  
  408.  
  409. /**********************************************************************/
  410. /*****           Accelerated point, line, polygon rendering       *****/
  411. /**********************************************************************/
  412.  
  413.  
  414. static void fast_rgb_points( GLcontext* ctx, GLuint first, GLuint last )
  415. {
  416.    GLuint i;
  417.  //  HDC DC=DD_GETDC;
  418.     PWMC    pwc = Current;
  419.      
  420.     STARTPROFILE
  421.  
  422.     if (Current->gl_ctx->VB->MonoColor) {
  423.       /* all drawn with current color */
  424.       for (i=first;i<=last;i++) {
  425.          if (Current->gl_ctx->VB->ClipMask[i]==0) {
  426.             int x, y;
  427.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  428.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  429.             wmSetPixel(pwc, y,x,GetRValue(Current->pixel), 
  430.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  431.          }
  432.       }
  433.    }
  434.    else {
  435.       /* draw points of different colors */
  436.       for (i=first;i<=last;i++) {
  437.          if (Current->gl_ctx->VB->ClipMask[i]==0) {
  438.             int x, y;
  439.             unsigned long pixel=RGB(Current->gl_ctx->VB->Color[i][0]*255.0,
  440.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  441.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  442.             x =       (GLint) Current->gl_ctx->VB->Win[i][0];
  443.             y = FLIP( (GLint) Current->gl_ctx->VB->Win[i][1] );
  444.             wmSetPixel(pwc, y,x,Current->gl_ctx->VB->Color[i][0]*255.0, 
  445.                                     Current->gl_ctx->VB->Color[i][1]*255.0,
  446.                                     Current->gl_ctx->VB->Color[i][2]*255.0);
  447.          }
  448.       }
  449.    }
  450. //   DD_RELEASEDC;
  451.    ENDPROFILE(fast_rgb_points)
  452. }
  453.  
  454.  
  455.  
  456. /* Return pointer to accerated points function */
  457. extern points_func choose_points_function( GLcontext* ctx )
  458. {
  459.    STARTPROFILE
  460.    if (ctx->Point.Size==1.0 && !ctx->Point.SmoothFlag && ctx->RasterMask==0
  461.        && !ctx->Texture.Enabled  && ctx->Visual->RGBAflag) {
  462.    ENDPROFILE(choose_points_function)
  463.       return fast_rgb_points;
  464.    }
  465.    else {
  466.    ENDPROFILE(choose_points_function)
  467.       return NULL;
  468.    }
  469. }
  470.  
  471.  
  472.  
  473. /* Draw a line using the color specified by Current->gl_ctx->VB->Color[pv] */
  474. static void fast_flat_rgb_line( GLcontext* ctx, GLuint v0, GLuint v1, GLuint pv )
  475. {
  476.     STARTPROFILE
  477.     int x0, y0, x1, y1;
  478.     unsigned long pixel;
  479.     HDC DC=DD_GETDC;
  480.     HPEN Pen;
  481.     HPEN Old_Pen;
  482.  
  483.     if (Current->gl_ctx->VB->MonoColor) {
  484.       pixel = Current->pixel;  /* use current color */
  485.     }
  486.     else {
  487.       pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  488.     }
  489.  
  490.     x0 =       (int) Current->gl_ctx->VB->Win[v0][0];
  491.     y0 = FLIP( (int) Current->gl_ctx->VB->Win[v0][1] );
  492.     x1 =       (int) Current->gl_ctx->VB->Win[v1][0];
  493.     y1 = FLIP( (int) Current->gl_ctx->VB->Win[v1][1] );
  494.  
  495.  
  496.     BEGINGDICALL
  497.  
  498.     Pen=CreatePen(PS_SOLID,1,pixel);
  499.     Old_Pen=SelectObject(DC,Pen);
  500.     MoveToEx(DC,x0,y0,NULL);
  501.     LineTo(DC,x1,y1);
  502.     SelectObject(DC,Old_Pen);
  503.     DeleteObject(Pen);
  504.     DD_RELEASEDC;
  505.  
  506.     ENDGDICALL
  507.  
  508.     ENDPROFILE(fast_flat_rgb_line)
  509. }
  510.  
  511.  
  512.  
  513. /* Return pointer to accerated line function */
  514. static line_func choose_line_function( GLcontext* ctx )
  515. {
  516.     STARTPROFILE
  517.    if (ctx->Line.Width==1.0 && !ctx->Line.SmoothFlag && !ctx->Line.StippleFlag
  518.        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  519.        && !ctx->Texture.Enabled && Current->rgb_flag) {
  520.    ENDPROFILE(choose_line_function)
  521.       return fast_flat_rgb_line;
  522.    }
  523.    else {
  524.    ENDPROFILE(choose_line_function)
  525.       return NULL;
  526.    }
  527. }
  528.  
  529. /**********************************************************************/
  530. /*****                 Optimized triangle rendering               *****/
  531. /**********************************************************************/
  532.  
  533.  
  534. /*
  535.  * Smooth-shaded, z-less triangle, RGBA color.
  536.  */
  537. static void smooth_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  538.                                      GLuint v2, GLuint pv )
  539. {
  540. UINT    nBypp = Current->cColorBits / 8;
  541. GLbyte* img;
  542. GLushort* img16;
  543. GLuint *img24 ,*img32;
  544. #define INTERP_Z 1
  545. #define INTERP_RGB 1
  546. #define INTERP_ALPHA 1
  547. #define INNER_LOOP( LEFT, RIGHT, Y )                            \
  548. {                                                                \
  549.    GLint i, len = RIGHT-LEFT;                                    \
  550.    img = PIXELADDR(LEFT,Y);                                       \
  551.    for (i=0;i<len;i++,img+=nBypp) {                                \
  552.       GLdepth z = FixedToDepth(ffz);                            \
  553.       if (z < zRow[i]) {                                        \
  554.          img16 = img24 = img32 = img;                            \
  555.          if(nBypp == 2)                                            \
  556.             *img16 = BGR16(    FixedToInt(ffr), FixedToInt(ffg),    \
  557.                             FixedToInt(ffb));                    \
  558.          if(nBypp == 3)                                            \
  559.             *img24 = BGR24(    FixedToInt(ffr), FixedToInt(ffg),    \
  560.                             FixedToInt(ffb));                    \
  561.             if(nBypp == 4)                                            \
  562.             *img32 = BGR32(    FixedToInt(ffr), FixedToInt(ffg),    \
  563.                             FixedToInt(ffb));                    \
  564.          zRow[i] = z;                                            \
  565.       }                                                            \
  566.       ffr += fdrdx;  ffg += fdgdx;  ffb += fdbdx;  ffa += fdadx;\
  567.       ffz += fdzdx;                                                \
  568.    }                                                            \
  569. }
  570.     
  571.     #include "tritemp.h"
  572.  }
  573.  
  574.  
  575.  
  576.  
  577. /*
  578.  * Flat-shaded, z-less triangle, RGBA color.
  579.  */
  580. static void flat_color_z_triangle( GLcontext *ctx, GLuint v0, GLuint v1,
  581.                                    GLuint v2, GLuint pv )
  582. {
  583. GLbyte* img;
  584. GLushort* img16;
  585. GLuint *img24, *img32;
  586. UINT    nBypp = Current->cColorBits / 8;
  587. GLubyte r, g, b ;
  588. GLushort pixel16 = BGR16(r,g,b);
  589. GLuint   pixel24 = BGR24(r,g,b);
  590. GLuint   pixel32 = BGR32(r,g,b);
  591.  
  592. #define INTERP_Z 1
  593. #define SETUP_CODE            \
  594.    r = VB->Color[pv][0];    \
  595.    g = VB->Color[pv][1];    \
  596.    b = VB->Color[pv][2];    
  597.  
  598. #define INNER_LOOP( LEFT, RIGHT, Y )                            \
  599. {                                                                \
  600.    GLint i, len = RIGHT-LEFT;                                    \
  601.    img = PIXELADDR(LEFT,Y);                                        \
  602.    for (i=0;i<len;i++,img+=nBypp) {                                \
  603.       GLdepth z = FixedToDepth(ffz);                            \
  604.       if (z < zRow[i]) {                                        \
  605.          img16 = img24 = img32 = img;                            \
  606.          if(nBypp == 2)                                            \
  607.             *img16 = pixel16;                                    \
  608.          if(nBypp == 3)                                            \
  609.             *img24 = pixel24;                                    \
  610.             if(nBypp == 4)                                            \
  611.             *img32 = pixel32;                                    \
  612.          zRow[i] = z;                                            \
  613.       }                                                            \
  614.       ffz += fdzdx;                                                \
  615.    }                                                            \
  616. }
  617.  
  618. #include "tritemp.h"
  619. }
  620.  
  621.  
  622.  
  623. /*
  624.  * Return pointer to an accelerated triangle function if possible.
  625.  */
  626. static triangle_func choose_triangle_function( GLcontext *ctx )
  627. {
  628.    if (ctx->Polygon.SmoothFlag)     return NULL;
  629.    if (ctx->Polygon.StippleFlag)    return NULL;
  630.    if (ctx->Texture.Enabled)        return NULL;
  631.  
  632.    if (ctx->RasterMask==DEPTH_BIT
  633.        && ctx->Depth.Func==GL_LESS
  634.        && ctx->Depth.Mask==GL_TRUE
  635.        && ctx->Visual->RGBAflag) {  
  636.     if (ctx->Light.ShadeModel==GL_SMOOTH) {
  637.          return smooth_color_z_triangle;
  638.       }
  639.       else {
  640.          return flat_color_z_triangle;
  641.       }
  642.    }
  643.    return NULL;
  644. }
  645.  
  646.  
  647. /* Draw a convex polygon using color Current->gl_ctx->VB->Color[pv] */
  648. static void fast_flat_rgb_polygon( GLcontext* ctx, GLuint n, GLuint vlist[], GLuint pv )
  649. {
  650.    STARTPROFILE
  651.    POINT *Pts=(POINT *) malloc(n*sizeof(POINT));
  652.    HDC DC=DD_GETDC;
  653.    HPEN Pen;
  654.    HBRUSH Brush;
  655.    HPEN Old_Pen;
  656.    HBRUSH Old_Brush;
  657.    GLint pixel;
  658.    GLuint i;
  659.  
  660.    if (Current->gl_ctx->VB->MonoColor) {
  661.       pixel = Current->pixel;  /* use current color */
  662.    }
  663.    else {
  664.       pixel = RGB(Current->gl_ctx->VB->Color[pv][0]*255.0, Current->gl_ctx->VB->Color[pv][1]*255.0, Current->gl_ctx->VB->Color[pv][2]*255.0);
  665.    }
  666.  
  667.    Pen=CreatePen(PS_SOLID,1,pixel);
  668.    Brush=CreateSolidBrush(pixel);
  669.    Old_Pen=SelectObject(DC,Pen);
  670.    Old_Brush=SelectObject(DC,Brush);
  671.  
  672.    for (i=0; i<n; i++) {
  673.       int j = vlist[i];
  674.       Pts[i].x =       (int) Current->gl_ctx->VB->Win[j][0];
  675.       Pts[i].y = FLIP( (int) Current->gl_ctx->VB->Win[j][1] );
  676.    }
  677.  
  678.    BEGINGDICALL
  679.  
  680.    Polygon(DC,Pts,n);
  681.    SelectObject(DC,Old_Pen);
  682.    SelectObject(DC,Old_Brush);
  683.    DeleteObject(Pen);
  684.    DeleteObject(Brush);
  685.    DD_RELEASEDC;
  686.    free(Pts);
  687.  
  688.    ENDGDICALL
  689.  
  690.   ENDPROFILE(fast_flat_rgb_polygon)
  691. }
  692.  
  693.  
  694.  
  695. /* Return pointer to accerated polygon function */
  696. static polygon_func choose_polygon_function( GLcontext* ctx )
  697. {
  698.     STARTPROFILE
  699.    if (!ctx->Polygon.SmoothFlag && !ctx->Polygon.StippleFlag
  700.        && ctx->Light.ShadeModel==GL_FLAT && ctx->RasterMask==0
  701.        && !ctx->Texture.Enabled && Current->rgb_flag==GL_TRUE) {
  702.    ENDPROFILE(choose_polygon_function)
  703.       return fast_flat_rgb_polygon;
  704.    }
  705.    else {
  706.    ENDPROFILE(choose_polygon_function)
  707.       return NULL;
  708.    }
  709. }
  710.  
  711.  
  712.  
  713. /**********************************************************************/
  714. /*****                 Span-based pixel drawing                   *****/
  715. /**********************************************************************/
  716.  
  717.  
  718. /* Write a horizontal span of color-index pixels with a boolean mask. */
  719. static void write_index_span( GLcontext* ctx, 
  720.                               GLuint n, GLint x, GLint y,
  721.                               const GLuint index[],
  722.                               const GLubyte mask[] )
  723. {
  724.       STARTPROFILE
  725.       GLuint i;
  726.       char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  727.       assert(Current->rgb_flag==GL_FALSE);
  728.       for (i=0; i<n; i++)
  729.         if (mask[i])
  730.           Mem[i]=index[i];
  731.        ENDPROFILE(write_index_span)
  732. }
  733.  
  734.  
  735.  
  736. /*
  737.  * Write a horizontal span of pixels with a boolean mask.  The current
  738.  * color index is used for all pixels.
  739.  */
  740. static void write_monoindex_span(GLcontext* ctx, 
  741.                                  GLuint n,GLint x,GLint y,
  742.                                  const GLubyte mask[])
  743. {
  744.       STARTPROFILE
  745.       GLuint i;
  746.       char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  747.       assert(Current->rgb_flag==GL_FALSE);
  748.       for (i=0; i<n; i++)
  749.         if (mask[i])
  750.           Mem[i]=Current->pixel;
  751.       ENDPROFILE(write_monoindex_span)
  752. }
  753.  
  754. /*
  755.     To improve the performance of this routine, frob the data into an actual scanline
  756.     and call bitblt on the complete scan line instead of SetPixel.
  757. */
  758.  
  759. /* Write a horizontal span of color pixels with a boolean mask. */
  760. static void write_color_span( GLcontext* ctx, 
  761.               GLuint n, GLint x, GLint y,
  762.               const GLubyte
  763.               red[], const GLubyte green[],
  764.               const GLubyte blue[], const GLubyte alpha[],
  765.               const GLubyte mask[] )
  766. {
  767.     STARTPROFILE
  768.  
  769.     PWMC    pwc = Current;
  770.  
  771.     if (pwc->rgb_flag==GL_TRUE)
  772.     {
  773.         GLuint i;
  774.         HDC DC=DD_GETDC;
  775.         y=FLIP(y);
  776.  
  777.         if (mask) {
  778.             for (i=0; i<n; i++)
  779.                 if (mask[i])
  780.                     wmSetPixel(pwc, y, x + i,red[i], green[i], blue[i]);
  781.         }
  782.  
  783.         else {
  784.             for (i=0; i<n; i++)
  785.                 wmSetPixel(pwc, y, x + i, red[i], green[i], blue[i]);
  786.         }
  787.  
  788.         DD_RELEASEDC;
  789.  
  790.     }
  791.  
  792.   else
  793.   {
  794.         GLuint i;
  795.         char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  796.         if (mask) {
  797.            for (i=0; i<n; i++)
  798.              if (mask[i])
  799.                Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  800.         }
  801.         else {
  802.            for (i=0; i<n; i++)
  803.              Mem[i]=GetNearestPaletteIndex(Current->hPal,RGB(red[i],green[i],blue[i]));
  804.             }
  805.     }
  806.    ENDPROFILE(write_color_span)
  807.  
  808. }
  809.  
  810. /*
  811.  * Write a horizontal span of pixels with a boolean mask.  The current color
  812.  * is used for all pixels.
  813.  */
  814. static void write_monocolor_span( GLcontext* ctx, 
  815.                                   GLuint n, GLint x, GLint y,
  816.                                   const GLubyte mask[])
  817. {
  818.   STARTPROFILE
  819.   GLuint i;
  820.   HDC DC=DD_GETDC;
  821.   PWMC    pwc = Current;
  822.  
  823.   assert(Current->rgb_flag==GL_TRUE);
  824.   y=FLIP(y);
  825.  
  826.   if(Current->rgb_flag==GL_TRUE){
  827.       for (i=0; i<n; i++)
  828.         if (mask[i])
  829. // Trying
  830.         wmSetPixel(pwc,y,x+i,GetRValue(Current->pixel), GetGValue(Current->pixel), GetBValue(Current->pixel));
  831.   }
  832.   else {
  833.       for (i=0; i<n; i++)
  834.         if (mask[i])
  835.             SetPixel(DC, y, x+i, Current->pixel);
  836.   }
  837.  
  838.     DD_RELEASEDC;
  839.  
  840.     ENDPROFILE(write_monocolor_span)
  841. }
  842.  
  843.  
  844.  
  845. /**********************************************************************/
  846. /*****                   Array-based pixel drawing                *****/
  847. /**********************************************************************/
  848.  
  849.  
  850. /* Write an array of pixels with a boolean mask. */
  851. static void write_index_pixels( GLcontext* ctx, 
  852.                                 GLuint n, const GLint x[], const GLint y[],
  853.                                 const GLuint index[], const GLubyte mask[] )
  854. {
  855.    STARTPROFILE
  856.    GLuint i;
  857.    assert(Current->rgb_flag==GL_FALSE);
  858.    for (i=0; i<n; i++) {
  859.       if (mask[i]) {
  860.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  861.            *Mem = index[i];
  862.       }
  863.    }
  864.    ENDPROFILE(write_index_pixels)
  865. }
  866.  
  867.  
  868.  
  869. /*
  870.  * Write an array of pixels with a boolean mask.  The current color
  871.  * index is used for all pixels.
  872.  */
  873. static void write_monoindex_pixels( GLcontext* ctx, 
  874.                                     GLuint n,
  875.                                     const GLint x[], const GLint y[],
  876.                                     const GLubyte mask[] )
  877. {
  878.    STARTPROFILE
  879.    GLuint i;
  880.    assert(Current->rgb_flag==GL_FALSE);
  881.    for (i=0; i<n; i++) {
  882.       if (mask[i]) {
  883.          char *Mem=Current->ScreenMem+y[i]*Current->ScanWidth+x[i];
  884.             *Mem = Current->pixel;
  885.       }
  886.    }
  887.    ENDPROFILE(write_monoindex_pixels)
  888. }
  889.  
  890.  
  891.  
  892. /* Write an array of pixels with a boolean mask. */
  893. static void write_color_pixels( GLcontext* ctx,
  894.                                 GLuint n, const GLint x[], const GLint y[],
  895.                                 const GLubyte r[], const GLubyte g[],
  896.                                 const GLubyte b[], const GLubyte a[],
  897.                                 const GLubyte mask[] )
  898. {
  899.     STARTPROFILE
  900.     GLuint i;
  901.     PWMC    pwc = Current;
  902.     HDC DC=DD_GETDC;
  903.     assert(Current->rgb_flag==GL_TRUE);
  904.     for (i=0; i<n; i++)
  905.         if (mask[i])
  906.             wmSetPixel(pwc, FLIP(y[i]),x[i],r[i],g[i],b[i]);
  907.     DD_RELEASEDC;
  908.     ENDPROFILE(write_color_pixels)
  909. }
  910.  
  911.  
  912.  
  913. /*
  914.  * Write an array of pixels with a boolean mask.  The current color
  915.  * is used for all pixels.
  916.  */
  917. static void write_monocolor_pixels( GLcontext* ctx,
  918.                                     GLuint n,
  919.                                     const GLint x[], const GLint y[],
  920.                                     const GLubyte mask[] )
  921. {
  922.     STARTPROFILE
  923.     GLuint i;
  924.     PWMC    pwc = Current;
  925.     HDC DC=DD_GETDC;
  926.     assert(Current->rgb_flag==GL_TRUE);
  927.     for (i=0; i<n; i++)
  928.         if (mask[i])
  929.             wmSetPixel(pwc, FLIP(y[i]),x[i],GetRValue(Current->pixel), 
  930.                         GetGValue(Current->pixel), GetBValue(Current->pixel));
  931.     DD_RELEASEDC;
  932.     ENDPROFILE(write_monocolor_pixels)
  933. }
  934.  
  935.  
  936.  
  937. /**********************************************************************/
  938. /*****            Read spans/arrays of pixels                     *****/
  939. /**********************************************************************/
  940.  
  941.  
  942. /* Read a horizontal span of color-index pixels. */
  943. static void read_index_span( GLcontext* ctx, GLuint n, GLint x, GLint y, GLuint index[])
  944. {
  945.   STARTPROFILE
  946.   GLuint i;
  947.   char *Mem=Current->ScreenMem+y*Current->ScanWidth+x;
  948.   assert(Current->rgb_flag==GL_FALSE);
  949.   for (i=0; i<n; i++)
  950.     index[i]=Mem[i];
  951.   ENDPROFILE(read_index_span)
  952.  
  953. }
  954.  
  955.  
  956.  
  957.  
  958. /* Read an array of color index pixels. */
  959. static void read_index_pixels( GLcontext* ctx, 
  960.                                GLuint n, const GLint x[], const GLint y[],
  961.                                GLuint indx[], const GLubyte mask[] )
  962. {
  963.    STARTPROFILE
  964.    GLuint i;
  965.   assert(Current->rgb_flag==GL_FALSE);
  966.   for (i=0; i<n; i++) {
  967.      if (mask[i]) {
  968.         indx[i]=*(Current->ScreenMem+y[i]*Current->ScanWidth+x[i]);
  969.      }
  970.   }
  971.    ENDPROFILE(read_index_pixels)
  972. }
  973.  
  974.  
  975.  
  976. /* Read a horizontal span of color pixels. */
  977. static void read_color_span( GLcontext* ctx, 
  978.                              GLuint n, GLint x, GLint y,
  979.                              GLubyte red[], GLubyte green[],
  980.                              GLubyte blue[], GLubyte alpha[] )
  981. {
  982.    STARTPROFILE
  983.   UINT i;
  984.   COLORREF Color;
  985.   HDC DC=DD_GETDC;
  986.   assert(Current->rgb_flag==GL_TRUE);
  987.   y=FLIP(y);
  988.   for (i=0; i<n; i++)
  989.   {
  990.     Color=GetPixel(DC,x+i,y);
  991.     red[i]=GetRValue(Color);
  992.     green[i]=GetGValue(Color);
  993.     blue[i]=GetBValue(Color);
  994.     alpha[i]=255;
  995.   }
  996.   DD_RELEASEDC;
  997.   memset(alpha,0,n*sizeof(GLint));
  998.    ENDPROFILE(read_color_span)
  999. }
  1000.  
  1001.  
  1002. /* Read an array of color pixels. */
  1003. static void read_color_pixels( GLcontext* ctx,
  1004.                                GLuint n, const GLint x[], const GLint y[],
  1005.                                GLubyte red[], GLubyte green[],
  1006.                                GLubyte blue[], GLubyte alpha[],
  1007.                                const GLubyte mask[] )
  1008. {
  1009.    STARTPROFILE
  1010.   GLuint i;
  1011.   COLORREF Color;
  1012.   HDC DC=DD_GETDC;
  1013.   assert(Current->rgb_flag==GL_TRUE);
  1014.   for (i=0; i<n; i++) {
  1015.      if (mask[i]) {
  1016.         Color=GetPixel(DC,x[i],FLIP(y[i]));
  1017.         red[i]=GetRValue(Color);
  1018.         green[i]=GetGValue(Color);
  1019.         blue[i]=GetBValue(Color);
  1020.         alpha[i]=255;
  1021.      }
  1022.   }
  1023.   DD_RELEASEDC;
  1024.   memset(alpha,0,n*sizeof(GLint));
  1025.    ENDPROFILE(read_color_pixels)
  1026. }
  1027.  
  1028.  
  1029.  
  1030. /**********************************************************************/
  1031. /**********************************************************************/
  1032.  
  1033.  
  1034.  
  1035. void setup_DD_pointers( GLcontext* ctx )
  1036. {
  1037.    ctx->Driver.Finish = finish;
  1038.    ctx->Driver.Flush = flush;
  1039.  
  1040.    ctx->Driver.ClearIndex = clear_index;
  1041.    ctx->Driver.ClearColor = clear_color;
  1042.    ctx->Driver.Clear = clear;
  1043.  
  1044.    ctx->Driver.Index = set_index;
  1045.    ctx->Driver.Color = set_color;
  1046.    ctx->Driver.IndexMask = index_mask;
  1047.    ctx->Driver.ColorMask = color_mask;
  1048.  
  1049.    ctx->Driver.LogicOp = logicop;
  1050.    ctx->Driver.Dither = dither;
  1051.  
  1052.    ctx->Driver.SetBuffer = set_buffer;
  1053.    ctx->Driver.GetBufferSize = buffer_size;
  1054.  
  1055.    ctx->Driver.PointsFunc = choose_points_function(ctx);
  1056.    ctx->Driver.LineFunc = choose_line_function(ctx);
  1057.    ctx->Driver.TriangleFunc = choose_triangle_function( ctx );
  1058.    //   ctx->Driver.TriangleFunc = choose_polygon_function(ctx);
  1059.  
  1060.    /* Pixel/span writing functions: */
  1061.    ctx->Driver.WriteColorSpan       = write_color_span;
  1062.    ctx->Driver.WriteMonocolorSpan   = write_monocolor_span;
  1063.    ctx->Driver.WriteColorPixels     = write_color_pixels;
  1064.    ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
  1065.    ctx->Driver.WriteIndexSpan       = write_index_span;
  1066.    ctx->Driver.WriteMonoindexSpan   = write_monoindex_span;
  1067.    ctx->Driver.WriteIndexPixels     = write_index_pixels;
  1068.    ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
  1069.  
  1070.    /* Pixel/span reading functions: */
  1071.    ctx->Driver.ReadIndexSpan = read_index_span;
  1072.    ctx->Driver.ReadColorSpan = read_color_span;
  1073.    ctx->Driver.ReadIndexPixels = read_index_pixels;
  1074.    ctx->Driver.ReadColorPixels = read_color_pixels;
  1075. }
  1076.  
  1077. //
  1078. // MesaGL32 is the DLL version of MesaGL for Win32
  1079. //
  1080.  
  1081. /**********************************************************************/
  1082. /*****                  WMesa API Functions                       *****/
  1083. /**********************************************************************/
  1084.  
  1085.  
  1086.  
  1087. #define PAL_SIZE 256
  1088. static void GetPalette(HPALETTE Pal,RGBQUAD *aRGB)
  1089. {
  1090.    STARTPROFILE
  1091.     int i;
  1092.     HDC hdc;
  1093.     struct
  1094.     {
  1095.         WORD Version;
  1096.         WORD NumberOfEntries;
  1097.         PALETTEENTRY aEntries[PAL_SIZE];
  1098.     } Palette =
  1099.     {
  1100.         0x300,
  1101.         PAL_SIZE
  1102.     };
  1103.     hdc=GetDC(NULL);
  1104.     if (Pal!=NULL)
  1105.     GetPaletteEntries(Pal,0,PAL_SIZE,Palette.aEntries);
  1106.   else
  1107.     GetSystemPaletteEntries(hdc,0,PAL_SIZE,Palette.aEntries);
  1108.     if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC)
  1109.     {
  1110.         for(i = 0; i <PAL_SIZE; i++)
  1111.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1112.         Palette.aEntries[255].peRed = 255;
  1113.         Palette.aEntries[255].peGreen = 255;
  1114.         Palette.aEntries[255].peBlue = 255;
  1115.         Palette.aEntries[255].peFlags = 0;
  1116.         Palette.aEntries[0].peRed = 0;
  1117.         Palette.aEntries[0].peGreen = 0;
  1118.         Palette.aEntries[0].peBlue = 0;
  1119.         Palette.aEntries[0].peFlags = 0;
  1120.     }
  1121.     else
  1122.     {
  1123.         int nStaticColors;
  1124.         int nUsableColors;
  1125.         nStaticColors = GetDeviceCaps(hdc, NUMCOLORS)/2;
  1126.         for (i=0; i<nStaticColors; i++)
  1127.             Palette.aEntries[i].peFlags = 0;
  1128.         nUsableColors = PAL_SIZE-nStaticColors;
  1129.         for (; i<nUsableColors; i++)
  1130.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1131.         for (; i<PAL_SIZE-nStaticColors; i++)
  1132.             Palette.aEntries[i].peFlags = PC_RESERVED;
  1133.         for (i=PAL_SIZE-nStaticColors; i<PAL_SIZE; i++)
  1134.             Palette.aEntries[i].peFlags = 0;
  1135.     }
  1136.     ReleaseDC(NULL,hdc);
  1137.   for (i=0; i<PAL_SIZE; i++)
  1138.   {
  1139.     aRGB[i].rgbRed=Palette.aEntries[i].peRed;
  1140.     aRGB[i].rgbGreen=Palette.aEntries[i].peGreen;
  1141.     aRGB[i].rgbBlue=Palette.aEntries[i].peBlue;
  1142.     aRGB[i].rgbReserved=Palette.aEntries[i].peFlags;
  1143.   }
  1144.         ENDPROFILE(GetPalette)
  1145. }
  1146.  
  1147.  
  1148. WMesaContext /*APIENTRY*/ WMesaCreateContext( HWND hWnd, HPALETTE Pal, 
  1149.                                              /*HDC hDC,*/ GLboolean rgb_flag,
  1150.                                               GLboolean db_flag )
  1151. {
  1152.   BITMAPINFO *Rec;
  1153.   //HDC DC;
  1154.   RECT CR;
  1155.   WMesaContext c;
  1156.    
  1157.   c = (struct wmesa_context * ) calloc(1,sizeof(struct wmesa_context));
  1158.   if (!c)
  1159.     return NULL;
  1160.  
  1161.   c->Window=hWnd;
  1162.   c->hDC = GetDC(hWnd);
  1163.   
  1164.   if (rgb_flag==GL_FALSE)
  1165.   {
  1166.     c->rgb_flag = GL_FALSE;
  1167.     c->pixel = 1;
  1168.     db_flag=GL_TRUE; // WinG requires double buffering
  1169.     //c->gl_ctx->BufferDepth = windepth;
  1170.   }
  1171.   else
  1172.   {
  1173.     c->rgb_flag = GL_TRUE;
  1174.     c->pixel = 0;
  1175.   }
  1176.   GetClientRect(c->Window,&CR);
  1177.   c->width=CR.right;
  1178.   c->height=CR.bottom;
  1179.   if (db_flag)
  1180.   {
  1181.     c->db_flag = 1;
  1182. //    c->hDC GetDC(c->Window);   
  1183.     /* Double buffered */
  1184.     if (c->rgb_flag==GL_TRUE)
  1185.     {
  1186.       //DC = c->hDC = hDC;
  1187.        
  1188. //        DC = c->hDC = GetDC(c->Window);
  1189.         wmCreateBackingStore(c, c->width, c->height);
  1190. //        ReleaseDC(c->Window,DC);
  1191.     }
  1192.     else
  1193.     {
  1194.       c->dib.hDC=WinGCreateDC();
  1195.       Rec=(BITMAPINFO *) malloc(sizeof(BITMAPINFO)+(PAL_SIZE-1)*sizeof(RGBQUAD));
  1196.       c->hPal=Pal;
  1197.       GetPalette(Pal,Rec->bmiColors);
  1198.       WinGRecommendDIBFormat(Rec);
  1199.       Rec->bmiHeader.biWidth=c->width;
  1200.       Rec->bmiHeader.biHeight*=c->height;
  1201.       Rec->bmiHeader.biClrUsed=PAL_SIZE;
  1202.       if (Rec->bmiHeader.biPlanes!=1 || Rec->bmiHeader.biBitCount!=8)
  1203.       {
  1204.         MessageBox(NULL,"Error.","This code presumes a 256 color, single plane, WinG Device.\n",MB_OK);
  1205.         exit(1);
  1206.       }
  1207.       c->Compat_BM=WinGCreateBitmap(c->dib.hDC,Rec,&((void *) c->ScreenMem));
  1208.       c->Old_Compat_BM=SelectObject(c->dib.hDC,c->Compat_BM);
  1209.       WinGSetDIBColorTable(c->dib.hDC,0,PAL_SIZE,Rec->bmiColors);
  1210.       c->IndexFormat=Rec;
  1211.       c->ScanWidth=c->width;
  1212.       c->cColorBits = 8;
  1213.       if ((c->ScanWidth%sizeof(long))!=0)
  1214.         c->ScanWidth+=(sizeof(long)-(c->ScanWidth%sizeof(long)));
  1215.     }
  1216.   }
  1217.   else
  1218.   {
  1219.     /* Single Buffered */
  1220.     c->db_flag = 0;
  1221.  
  1222. //    wmCreateBackingStore(c, c->width, c->height);
  1223.   }
  1224.  
  1225.   
  1226.   
  1227.   c->gl_visual = gl_create_visual(rgb_flag,
  1228.                                   GL_FALSE,    /* software alpha */
  1229.                                   db_flag,    /* db_flag */
  1230.                                   16,        /* depth_bits */
  1231.                                   8,        /* stencil_bits */
  1232.                                   8,        /* accum_bits */
  1233.                                   8,
  1234.                                   255.0, 255.0, 255.0, 255.0 );    
  1235.   
  1236.     if (!c->gl_visual) {
  1237.          return NULL;
  1238.       }
  1239.  
  1240.   /* allocate a new Mesa context */
  1241.   c->gl_ctx = gl_create_context( c->gl_visual, NULL,c);
  1242.  
  1243.   if (!c->gl_ctx) {
  1244.          gl_destroy_visual( c->gl_visual );
  1245.          free(c);
  1246.          return NULL;
  1247.       }
  1248.  
  1249.       c->gl_buffer = gl_create_framebuffer( c->gl_visual );
  1250.       if (!c->gl_buffer) {
  1251.          gl_destroy_visual( c->gl_visual );
  1252.          gl_destroy_context( c->gl_ctx );
  1253.          free(c);
  1254.          return NULL;
  1255.       }
  1256. //  setup_DD_pointers(c->gl_ctx);
  1257.  
  1258.   return c;
  1259. }
  1260.  
  1261.  
  1262.  
  1263. void /*APIENTRY*/ WMesaDestroyContext( void )
  1264. {
  1265.     WMesaContext c = Current;
  1266.     ReleaseDC(c->Window,c->hDC);
  1267.     WC = c;
  1268.  
  1269.     gl_destroy_visual( c->gl_visual );
  1270.     gl_destroy_framebuffer( c->gl_buffer );
  1271.     gl_destroy_context( c->gl_ctx );
  1272.  
  1273.     if (c->db_flag){
  1274.         wmDeleteBackingStore(c);
  1275.  
  1276. //Code added by Li Wei to enable parallel render
  1277. #if !defined(NO_STEREO)
  1278.         if(stereoBuffer==GL_TRUE){
  1279.             WMesaDestroyStereoBuffer();
  1280.             stereoBuffer=GL_FALSE;
  1281.         }
  1282. #endif 
  1283. // End modification
  1284.     }
  1285.     free( (void *) c );
  1286. //Code added by Li Wei to enable parallel render
  1287. // Parallel render only work in double buffer mode
  1288. #if !defined(NO_PARALLEL)
  1289.     if(parallelMachine)
  1290.         PRDestroyRenderBuffer();
  1291. #endif
  1292. // End modification
  1293. }
  1294.  
  1295.  
  1296.  
  1297. void /*APIENTRY*/ WMesaMakeCurrent( WMesaContext c )
  1298. {
  1299.     if(!c){
  1300.         Current = c;
  1301.         return;
  1302.     }
  1303.     
  1304.     //
  1305.     // A little optimization
  1306.     // If it already is current,
  1307.     // don't set it again
  1308.     //
  1309.     if(Current == c)
  1310.         return;
  1311.  
  1312.     //gl_set_context( c->gl_ctx );
  1313.     gl_make_current(c->gl_ctx, c->gl_buffer);
  1314.     Current = c;
  1315.     setup_DD_pointers(c->gl_ctx);
  1316.     if (Current->gl_ctx->Viewport.Width==0) {
  1317.       /* initialize viewport to window size */
  1318.       gl_Viewport( Current->gl_ctx,
  1319.                    0, 0, Current->width, Current->height );
  1320.     }
  1321. }
  1322.  
  1323.  
  1324.  
  1325. void /*APIENTRY*/ WMesaSwapBuffers( void )
  1326. {
  1327.   HDC DC = Current->hDC;
  1328.   if (Current->db_flag)
  1329.   {
  1330.     if (Current->rgb_flag)
  1331.         wmFlush(Current);
  1332.     else
  1333.       WinGBitBlt(DC,0,0,Current->width,Current->height,Current->dib.hDC,0,0);
  1334.   }
  1335. }
  1336.  
  1337.  
  1338.  
  1339. void /*APIENTRY*/ WMesaPaletteChange(HPALETTE Pal)
  1340. {
  1341.   if (Current && Current->rgb_flag==GL_FALSE)
  1342.   {
  1343.     Current->hPal=Pal;
  1344.     GetPalette(Pal,Current->IndexFormat->bmiColors);
  1345.     WinGSetDIBColorTable(Current->dib.hDC,0,PAL_SIZE,Current->IndexFormat->bmiColors);
  1346.   }
  1347. }
  1348.  
  1349. //
  1350. // Free up the dib section that was created
  1351. //
  1352. BOOL wmDeleteBackingStore(PWMC pwc)
  1353. {
  1354.     SelectObject(pwc->dib.hDC, pwc->hOldBitmap);
  1355.     DeleteDC(pwc->dib.hDC);
  1356.     DeleteObject(pwc->hbmDIB);
  1357.     UnmapViewOfFile(pwc->dib.base);
  1358.     CloseHandle(pwc->dib.hFileMap);
  1359.     return TRUE;
  1360. }
  1361.  
  1362.  
  1363. //
  1364. // This function creates the DIB section that is used for combined
  1365. // GL and GDI calls
  1366. //
  1367. BOOL /*WINAPI*/ wmCreateBackingStore(PWMC pwc, long lxSize, long lySize)
  1368. {
  1369.     HDC hdc = pwc->hDC;
  1370.     LPBITMAPINFO pbmi = &(pwc->bmi);
  1371.     int        iUsage;
  1372.  
  1373.     pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  1374.     pbmi->bmiHeader.biWidth = lxSize;
  1375.     pbmi->bmiHeader.biHeight= -lySize;
  1376.     pbmi->bmiHeader.biPlanes = 1;
  1377.     pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwc->hDC, BITSPIXEL);
  1378.     pbmi->bmiHeader.biCompression = BI_RGB;
  1379.     pbmi->bmiHeader.biSizeImage = 0;
  1380.     pbmi->bmiHeader.biXPelsPerMeter = 0;
  1381.     pbmi->bmiHeader.biYPelsPerMeter = 0;
  1382.     pbmi->bmiHeader.biClrUsed = 0;
  1383.     pbmi->bmiHeader.biClrImportant = 0;
  1384.  
  1385.     iUsage = (pbmi->bmiHeader.biBitCount <= 8) ? DIB_PAL_COLORS : DIB_RGB_COLORS;
  1386.  
  1387.     pwc->cColorBits = pbmi->bmiHeader.biBitCount;
  1388.     pwc->ScanWidth = lxSize;
  1389.  
  1390.     wmCreateDIBSection(hdc, pwc, pbmi, iUsage);
  1391.  
  1392.     if ((iUsage == DIB_PAL_COLORS) && !(pwc->hGLPalette)) {
  1393.         wmCreatePalette( pwc );
  1394.         wmSetDibColors( pwc );
  1395.     }
  1396.  
  1397.     return(TRUE);
  1398.  
  1399. }
  1400.  
  1401.  
  1402. //
  1403. // This function copies one scan line in a DIB section to another
  1404. //
  1405. BOOL WINAPI wmSetDIBits(PWMC pwc, UINT uiScanWidth, UINT uiNumScans, UINT nBypp, UINT uiNewWidth, LPBYTE pBits)
  1406. {
  1407.     UINT uiScans = 0;
  1408.     LPBYTE    pDest = pwc->pbPixels;
  1409.     DWORD    dwNextScan = uiScanWidth;
  1410.     DWORD    dwNewScan = uiNewWidth;
  1411.     DWORD    dwScanWidth = (uiScanWidth * nBypp);
  1412.  
  1413.     //
  1414.     // We need to round up to the nearest DWORD
  1415.     // and multiply by the number of bytes per
  1416.     // pixel
  1417.     //
  1418.     dwNextScan = (((dwNextScan * nBypp)+ 3) & ~3);
  1419.     dwNewScan = (((dwNewScan * nBypp)+ 3) & ~3);
  1420.  
  1421.     for(uiScans = 0; uiScans < uiNumScans; uiScans++){
  1422.         CopyMemory(pDest, pBits, dwScanWidth);
  1423.         pBits += dwNextScan;
  1424.         pDest += dwNewScan;
  1425.     }
  1426.  
  1427.     return(TRUE);
  1428.  
  1429. }
  1430.  
  1431. BOOL WINAPI wmSetPixelFormat( PWMC pwdc, HDC hDC, DWORD dwFlags )
  1432. {
  1433.     return(TRUE);
  1434. }
  1435.  
  1436. static unsigned char threeto8[8] = {
  1437.     0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
  1438. };
  1439.  
  1440. static unsigned char twoto8[4] = {
  1441.     0, 0x55, 0xaa, 0xff
  1442. };
  1443.  
  1444. static unsigned char oneto8[2] = {
  1445.     0, 255
  1446. };
  1447.  
  1448. static unsigned char componentFromIndex(UCHAR i, UINT nbits, UINT shift)
  1449. {
  1450.     unsigned char val;
  1451.  
  1452.     val = i >> shift;
  1453.     switch (nbits) {
  1454.  
  1455.         case 1:
  1456.             val &= 0x1;
  1457.             return oneto8[val];
  1458.  
  1459.         case 2:
  1460.             val &= 0x3;
  1461.             return twoto8[val];
  1462.  
  1463.         case 3:
  1464.             val &= 0x7;
  1465.             return threeto8[val];
  1466.  
  1467.         default:
  1468.             return 0;
  1469.     }
  1470. }
  1471.  
  1472. void /*WINAPI*/ wmCreatePalette( PWMC pwdc )
  1473. {
  1474.     /* Create a compressed and re-expanded 3:3:2 palette */
  1475.       int            i;
  1476.     LOGPALETTE     *pPal;
  1477.     BYTE           rb, rs, gb, gs, bb, bs;
  1478.  
  1479.     pwdc->nColors = 0x100;
  1480.  
  1481.     pPal = (PLOGPALETTE)malloc(sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY));
  1482.     memset( pPal, 0, sizeof(LOGPALETTE) + pwdc->nColors * sizeof(PALETTEENTRY) );
  1483.  
  1484.     pPal->palVersion = 0x300;
  1485.  
  1486.     rb = REDBITS;
  1487.     rs = REDSHIFT;
  1488.     gb = GREENBITS;
  1489.     gs = GREENSHIFT;
  1490.     bb = BLUEBITS;
  1491.     bs = BLUESHIFT;
  1492.  
  1493.     if (pwdc->db_flag) {
  1494.  
  1495.         /* Need to make two palettes: one for the screen DC and one for the DIB. */
  1496.         pPal->palNumEntries = pwdc->nColors;
  1497.         for (i = 0; i < pwdc->nColors; i++) {
  1498.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1499.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1500.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1501.             pPal->palPalEntry[i].peFlags = 0;
  1502.         }
  1503.         pwdc->hGLPalette = CreatePalette( pPal );
  1504.         pwdc->hPalette = CreatePalette( pPal );
  1505.     } 
  1506.  
  1507.     else {
  1508.         pPal->palNumEntries = pwdc->nColors;
  1509.         for (i = 0; i < pwdc->nColors; i++) {
  1510.             pPal->palPalEntry[i].peRed = componentFromIndex( i, rb, rs );
  1511.             pPal->palPalEntry[i].peGreen = componentFromIndex( i, gb, gs );
  1512.             pPal->palPalEntry[i].peBlue = componentFromIndex( i, bb, bs );
  1513.             pPal->palPalEntry[i].peFlags = 0;
  1514.         }
  1515.         pwdc->hGLPalette = CreatePalette( pPal );
  1516.     }
  1517.     
  1518.     free(pPal);
  1519.  
  1520. }
  1521.  
  1522. //
  1523. // This function sets the color table of a DIB section
  1524. // to match that of the destination DC
  1525. //
  1526. BOOL /*WINAPI*/ wmSetDibColors(PWMC pwc)
  1527. {
  1528.     RGBQUAD            *pColTab, *pRGB;
  1529.     PALETTEENTRY    *pPal, *pPE;
  1530.     int                i, nColors;
  1531.     BOOL            bRet=TRUE;
  1532.     DWORD            dwErr=0;
  1533.  
  1534.     /* Build a color table in the DIB that maps to the
  1535.        selected palette in the DC.
  1536.     */
  1537.     nColors = 1 << pwc->cColorBits;
  1538.     pPal = (PALETTEENTRY *)malloc( nColors * sizeof(PALETTEENTRY));
  1539.     memset( pPal, 0, nColors * sizeof(PALETTEENTRY) );
  1540.     GetPaletteEntries( pwc->hGLPalette, 0, nColors, pPal );
  1541.     pColTab = (RGBQUAD *)malloc( nColors * sizeof(RGBQUAD));
  1542.     for (i = 0, pRGB = pColTab, pPE = pPal; i < nColors; i++, pRGB++, pPE++) {
  1543.         pRGB->rgbRed = pPE->peRed;
  1544.         pRGB->rgbGreen = pPE->peGreen;
  1545.         pRGB->rgbBlue = pPE->peBlue;
  1546.     }
  1547.     if(pwc->db_flag)
  1548.         bRet = SetDIBColorTable(pwc->hDC, 0, nColors, pColTab );
  1549.  
  1550.     if(!bRet)
  1551.         dwErr = GetLastError();
  1552.  
  1553.     free( pColTab );
  1554.     free( pPal );
  1555.  
  1556.     return(bRet);
  1557. }
  1558.  
  1559. void /*WINAPI*/ wmSetPixel(PWMC pwc, int iScanLine, int iPixel, BYTE r, BYTE g, BYTE b)
  1560. {
  1561.     if(Current->db_flag){
  1562.         LPBYTE    lpb = pwc->pbPixels;
  1563.         LPDWORD    lpdw;
  1564.         LPWORD    lpw;
  1565.         UINT    nBypp = pwc->cColorBits / 8;
  1566.         UINT    nOffset = iPixel % nBypp;
  1567.  
  1568.         // Move the pixel buffer pointer to the scanline that we
  1569.         // want to access
  1570.  
  1571.         pwc->dib.fFlushed = FALSE;
  1572.  
  1573.         lpb += pwc->ScanWidth * iScanLine;
  1574.         // Now move to the desired pixel
  1575.         lpb += iPixel * nBypp;
  1576.  
  1577.         lpdw = (LPDWORD)lpb;
  1578.         lpw = (LPWORD)lpb;
  1579.  
  1580.         if(nBypp == 2)
  1581.             *lpw = BGR16(r,g,b);
  1582.         else if (nBypp == 3){
  1583.             *lpdw = BGR24(r,g,b);
  1584.         }
  1585.         else
  1586.             *lpdw = BGR32(r,g,b);
  1587.     }
  1588.     else{
  1589.         HDC DC = DD_GETDC;
  1590.         SetPixel(DC, iPixel, iScanLine, RGB(r,g,b));
  1591.         DD_RELEASEDC;
  1592.     }
  1593. }
  1594.  
  1595. void /*WINAPI*/ wmCreateDIBSection(
  1596.     HDC     hDC,
  1597.     PWMC pwc,    // handle of device context
  1598.     CONST BITMAPINFO *pbmi,    // address of structure containing bitmap size, format, and color data
  1599.     UINT iUsage    // color data type indicator: RGB values or palette indices
  1600. )
  1601. {
  1602.     DWORD    dwSize = 0;
  1603.     DWORD    dwScanWidth;
  1604.     UINT    nBypp = pwc->cColorBits / 8;
  1605.     HDC        hic;
  1606.     
  1607.     dwScanWidth = (((pwc->ScanWidth * nBypp)+ 3) & ~3);
  1608.  
  1609.     pwc->ScanWidth = dwScanWidth;
  1610.  
  1611.     dwSize = sizeof(BITMAPINFO) + (dwScanWidth * pwc->height);
  1612.  
  1613.     pwc->dib.hFileMap = CreateFileMapping((HANDLE)PAGE_FILE,
  1614.                                           NULL,
  1615.                                           PAGE_READWRITE | SEC_COMMIT,
  1616.                                           0,
  1617.                                           dwSize,
  1618.                                           NULL);
  1619.  
  1620.     if (!pwc->dib.hFileMap)
  1621.         return;
  1622.  
  1623.     pwc->dib.base = MapViewOfFile(pwc->dib.hFileMap,
  1624.                                   FILE_MAP_ALL_ACCESS,
  1625.                                   0,
  1626.                                   0,
  1627.                                   0);
  1628.  
  1629.     if(!pwc->dib.base){
  1630.         CloseHandle(pwc->dib.hFileMap);
  1631.         return;
  1632.     }
  1633.  
  1634.     pwc->pbPixels = ((LPBYTE)pwc->dib.base) + sizeof(BITMAPINFO);
  1635.     
  1636.     pwc->dib.hDC = CreateCompatibleDC(hDC);
  1637.  
  1638.     CopyMemory(pwc->dib.base, pbmi, sizeof(BITMAPINFO));
  1639.  
  1640.     hic = CreateIC("display", NULL, NULL, NULL);
  1641.  
  1642. /*    pwc->hbmDIB = CreateDIBitmap(hic,
  1643.                          &(pwc->bmi.bmiHeader),
  1644.                          CBM_INIT,
  1645.                          pwc->pbPixels,
  1646.                          &(pwc->bmi),
  1647.                          DIB_RGB_COLORS);
  1648. */
  1649.   pwc->hbmDIB = CreateDIBSection(hic,
  1650.                         &(pwc->bmi.bmiHeader),
  1651.                         DIB_RGB_COLORS,
  1652.                         &(pwc->pbPixels),
  1653.                         pwc->dib.hFileMap,
  1654.                         0);
  1655.     pwc->hOldBitmap = SelectObject(pwc->dib.hDC, pwc->hbmDIB);
  1656.  
  1657.     DeleteDC(hic);
  1658.  
  1659.     return;
  1660.  
  1661. }
  1662.  
  1663. //
  1664. // Blit memory DC to screen DC
  1665. //
  1666. BOOL /*WINAPI*/ wmFlush(PWMC pwc)
  1667. {
  1668.     BOOL    bRet = 0;
  1669.     DWORD    dwErr = 0;
  1670.  
  1671.  
  1672. //    wmFlushBits(pwc);
  1673.  
  1674.     bRet = BitBlt(pwc->hDC, 0, 0, pwc->width, pwc->height, 
  1675.            pwc->dib.hDC, 0, 0, SRCCOPY);
  1676.  
  1677.     if(!bRet)
  1678.         dwErr = GetLastError();
  1679.  
  1680.     pwc->dib.fFlushed = TRUE;
  1681.  
  1682.     return(TRUE);
  1683.  
  1684. }
  1685.  
  1686.  
  1687. // The following code is added by Li Wei to enable stereo display
  1688.  
  1689. #if !defined(NO_STEREO)
  1690.  
  1691. void WMesaCreateStereoBuffer()
  1692. {
  1693.     /* Must use double buffer and not in parallelMode */
  1694.     if (! Current->db_flag 
  1695. #if !defined(NO_PARALLEL)
  1696.         || parallelFlag
  1697. #endif        
  1698.         )
  1699.         return;
  1700.  
  1701.     Buffer_Stereo = malloc( Current->ScanWidth * Current->height);
  1702.     ZeroMemory(Buffer_Stereo,Current->ScanWidth * Current->height);
  1703.     stereoBuffer = GL_TRUE ;
  1704. }
  1705.  
  1706. void WMesaDestroyStereoBuffer()
  1707. {
  1708.     /* Must use double buffer and not in parallelMode */
  1709.     if (! Current->db_flag 
  1710. #if !defined(NO_PARALLEL)
  1711.         || parallelFlag
  1712. #endif        
  1713.         )
  1714.         return;
  1715.     if(stereoBuffer){
  1716.         free(Buffer_Stereo);
  1717.         stereoBuffer = GL_FALSE ;
  1718.     }
  1719. }
  1720.  
  1721. void WMesaInterleave(GLenum aView)
  1722. {
  1723.     int offset;
  1724.     unsigned line;
  1725.     LPBYTE dest;
  1726.     LPBYTE src;
  1727.     if(aView == FIRST)
  1728.         offset = 0;
  1729.     else offset = 1;
  1730.  
  1731.     dest = Buffer_Stereo + offset * Current->ScanWidth;
  1732.     if(Current->rgb_flag )
  1733.         src = Current->pbPixels + Current->ScanWidth*(Current->height/2);
  1734.     else
  1735.         src = Current->ScreenMem;
  1736.  
  1737.     for(line = 0; line<Current->height/2; line ++){
  1738.         CopyMemory(dest, src, Current->ScanWidth);
  1739.         dest += 2*Current->ScanWidth;
  1740.         src += Current->ScanWidth;
  1741.     }
  1742.     if(aView == SECOND)
  1743.         if(Current->rgb_flag)
  1744.             CopyMemory(Current->pbPixels, Buffer_Stereo, Current->ScanWidth*Current->height);
  1745.         else
  1746.             CopyMemory(Current->ScreenMem, Buffer_Stereo, Current->ScanWidth*Current->height);
  1747. }
  1748.  
  1749. void WMesaShowStereo(GLuint list)
  1750. {
  1751.  
  1752.     GLbitfield mask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
  1753.     GLfloat cm[16];
  1754.     // Must use double Buffer 
  1755.     if( ! Current-> db_flag )
  1756.         return;
  1757.  
  1758.     glViewport(0,0,Current->width,Current->height/2);
  1759.  
  1760.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1761.     glMatrixMode(GL_MODELVIEW);
  1762.     glLoadIdentity();
  1763.     gluLookAt(viewDistance/2,0.0,0.0 ,
  1764.              viewDistance/2,0.0,-1.0,
  1765.              0.0,1.0,0.0 );
  1766.     glMultMatrixf( cm );
  1767.     glMatrixMode(GL_MODELVIEW);
  1768.     glPushMatrix();
  1769.     glCallList( list );
  1770.     glPopMatrix();
  1771.     glFlush();
  1772.     WMesaInterleave( FIRST );
  1773.  
  1774.     glGetFloatv(GL_MODELVIEW_MATRIX,cm);
  1775.     glMatrixMode(GL_MODELVIEW);
  1776.     glLoadIdentity();
  1777.     gluLookAt(-viewDistance/2,0.0,0.0 ,
  1778.              -viewDistance/2,0.0,-1.0,
  1779.              0.0,1.0,0.0 );
  1780.     glMultMatrixf(cm);
  1781.     glMatrixMode(GL_MODELVIEW);
  1782.     glCallList(list);
  1783.     glFlush();
  1784.     WMesaInterleave( SECOND );
  1785.     glViewport(0,0,Current->width,Current->height);
  1786.     WMesaSwapBuffers();
  1787.  
  1788. }
  1789.  
  1790. void toggleStereoMode()
  1791. {
  1792.     if(!Current->db_flag)
  1793.         return;
  1794.     if(!stereo_flag){
  1795.         stereo_flag = 1;
  1796.         if(stereoBuffer==GL_FALSE)
  1797. #if !defined(NO_PARALLEL)
  1798.             if(!parallelFlag)
  1799. #endif
  1800.         {
  1801.             WMesaCreateStereoBuffer();
  1802.             }
  1803.     }
  1804.     else {
  1805.         stereo_flag = 0;
  1806.     if(stereoBuffer==GL_TRUE)
  1807. #if !defined(NO_PARALLEL)
  1808.         if(!parallelFlag)
  1809. #endif
  1810.             if(stereoBuffer==GL_TRUE){
  1811.                 WMesaDestroyStereoBuffer();
  1812.             }
  1813.     }
  1814. }
  1815.  
  1816. /* if in stereo mode, the following function is called */
  1817. void glShowStereo(GLuint list)
  1818. {
  1819.     WMesaShowStereo(list);
  1820. }
  1821.  
  1822. #endif // End if NO_STEREO not defined
  1823.  
  1824. #if !defined(NO_PARALLEL)
  1825.  
  1826. void toggleParallelMode(void)
  1827. {
  1828.     if(!parallelFlag){
  1829.         parallelFlag = GL_TRUE;
  1830.         if(parallelMachine==GL_FALSE){
  1831.                 PRCreateRenderBuffer( Current->rgb_flag? GL_RGBA :GL_COLOR_INDEX,
  1832.                                       Current->cColorBits/8,
  1833.                                       Current->width ,Current->height, 
  1834.                                       Current->ScanWidth,
  1835.                                       Current->rgb_flag? Current->pbPixels: Current->ScreenMem);
  1836.                 parallelMachine = GL_TRUE;
  1837.                 }
  1838.         }
  1839.     else {
  1840.         parallelFlag = GL_FALSE;
  1841.         if(parallelMachine==GL_TRUE){
  1842.                 PRDestroyRenderBuffer();
  1843.                 parallelMachine=GL_FALSE;
  1844.                 ReadyForNextFrame = GL_TRUE;
  1845.                 }
  1846.  
  1847. /***********************************************
  1848. // Seems something wrong!!!! 
  1849. ************************************************/
  1850.  
  1851.         WMesaMakeCurrent(Current);
  1852. #if !defined(NO_STEREO)
  1853.         stereo_flag = GL_FALSE ;
  1854. #endif
  1855.     }
  1856. }
  1857.  
  1858. void PRShowRenderResult(void)
  1859. {
  1860.     int flag = 0;
  1861. if(!glImageRendered())
  1862.         return;
  1863.  
  1864.   if (parallelFlag)
  1865.     {
  1866.       WMesaSwapBuffers();
  1867.      }
  1868.  
  1869. }
  1870. #endif //End if NO_PARALLEL not defined
  1871.  
  1872. //end modification
  1873.